package it.free.maya.worddistinct;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

/**
 * Load a solr stopwords file, using its content to remove stopwords from 
 * a list of loaded words
 * @author Stefano Falconetti
 */
public class WordsStopWordsFilter {

	private File stopWordsFile = null;
	private HashMap<String, Word> wordsList = null;
	private HashMap<String, Pattern> stopListRegExpPatterns = null;
	
	private static Logger logger = Logger.getLogger(WordsStopWordsFilter.class);
	
	/**
	 * Class builder, note that this class modify the copy of the words list passed
	 * @param stopWords is the file of solr stop words
	 */
	public WordsStopWordsFilter(File stopWords){
		this.stopWordsFile = stopWords;
	}
	
	/**
	 * Do the filtering
	 * @return the map of words cleaned out of stop words found in the file
	 */
	private void loadStopWords() throws Exception {
		
		
		if( (this.stopWordsFile == null) ||
			(!this.stopWordsFile.exists()) ){
			throw new Exception("Unable to read stop words file: [" + this.stopWordsFile + "]");
		}
		
		logger.info("Stop words list loading beging");
		
		int counter = 1;
		
		this.wordsList = new HashMap<String, Word>();
		
		BufferedReader bufferedReader = null;
		
		String oneLine = "";
		Word tmpWord = null;
		
		try{
			bufferedReader = new BufferedReader(new FileReader(this.stopWordsFile));
		    while(oneLine != null){
		    	  oneLine = bufferedReader.readLine();
		    	  if(oneLine != null){
		    		 if(!oneLine.startsWith("#")){
		    			oneLine = oneLine.trim();
		    			tmpWord = new Word();
		    			tmpWord.setWord(oneLine);
		    			this.wordsList.put(oneLine, tmpWord);
		    			logger.info((counter++) +  " loaded stopword: [" + oneLine + "]");
		    		 }
		    	  }
		    }
		}finally{
			     if(bufferedReader != null){
			        bufferedReader.close();
			        logger.info("Stop words list loading completed");
			     }
		}
	}
	
	/**
	 * Precompile all pattern, so that at runtime it is faster
	 */
	private void preCompileRegExpPatterns(){
		
		if( (this.wordsList == null) ||
			(this.wordsList.size() == 0) ){
			logger.error("Unable to precompile string replacement reg exp patterns, please verify.");
			return;
		}
		
		this.stopListRegExpPatterns = new HashMap<String, Pattern>();
		
		Set<String> stopListSet = this.wordsList.keySet();
		
		String tmpRegExp = null;
		
		Pattern tmpPattern = null;
		for(String tmp: stopListSet){
			tmpRegExp = "\\b" + tmp.trim() + "\\b";
			tmpPattern = Pattern.compile(tmpRegExp, Pattern.CASE_INSENSITIVE);
			this.stopListRegExpPatterns.put(tmp, tmpPattern);
		}
	}
	
	/**
	 * Activate the stop words filtering process, to act over a map passed in the constructor
	 * @return the class input words, cleaned out of stop words found in the file whose descriptor has been passed.
	 * @throws Exception
	 */
	public void init() throws Exception {
		this.loadStopWords();
		this.preCompileRegExpPatterns();
	}
	
	public Set<String> getStopWords(){
		
		Set<String> stopWordsListSet = null;
		
		if(this.wordsList != null){
			stopWordsListSet = this.wordsList.keySet();
		}
		
		return stopWordsListSet;
	}
	
	/**
	 * Return the regular expressions pre-compiled patterns to be used to replace substring
	 * @return a list of Pattern objects
	 */
	public HashMap<String, Pattern> getReplacementRegExpPatterns(){
		return this.stopListRegExpPatterns;
	}
	
	/**
	 * Replace in the input string the stopwords
	 * @param input is the string to operate replacement over
	 * @param replacement is the string to be set where a stop word is found
	 * @return the input with stop words replace by substitution string
	 */
	public String replaceStopWords(String input, String replacement) throws Exception {
		
		Pattern tmpPattern = null;
		Matcher tmpMatcher = null;
		
		for(String tmp: this.stopListRegExpPatterns.keySet()){
			
			if(!tmp.equals("")){
			   tmpPattern = stopListRegExpPatterns.get(tmp);
			   tmpMatcher = tmpPattern.matcher(input);
			   input = tmpMatcher.replaceAll(replacement).trim();
			}
		}
		return input;
	}
	
	/**
	 * Testing entry point
	 * @param args
	 */
	public static final void main(String args[]){
		WordsStopWordsFilter wordsStopWordsFilter = new WordsStopWordsFilter(new File("/home/c012426/dev/maya/apache-solr-1.4.0_core_search/conf/stopwords.txt"));
		try {
			wordsStopWordsFilter.init();
			
			Set<String> stopListSet = wordsStopWordsFilter.getStopWords();
			
			System.out.println(">> " + stopListSet);
			
			String product_name_input = "stia credo abbiate stia fretta stia ccstia";
			
			String product_name_output = wordsStopWordsFilter.replaceStopWords(product_name_input, "");
			System.out.println("Per row value transformation: [" + product_name_input + "] to [" + product_name_output + "]");
			
		} catch (Exception exc) {
			// TODO Auto-generated catch block
			exc.printStackTrace();
		}
	}
}
 